#ifndef CHATSERVICE_H
#define CHATSERVICE_H

#include <muduo/net/TcpConnection.h>
#include <iostream>
#include <unordered_map>
#include <functional>
#include <pthread.h>
#include <mutex>
#include "json.hpp"
#include "public.hpp"
#include "UserModel.hpp"
#include "OfflineMessageModel.hpp"
#include "FriendModel.hpp"
#include "GroupModel.hpp"
#include "redis.hpp"
using json = nlohmann::json;
using namespace std::placeholders;

// 第一个参数是 对方的TcpConnection信息，第二个参数是对方发过来的完整信息，第三个参数是 时间
using handler = std::function<void(const muduo::net::TcpConnectionPtr &conn, json &js, muduo::Timestamp)>;

class ChatService
{
public:
    static ChatService *instance();
    // 登录业务
    void Login(const muduo::net::TcpConnectionPtr &conn, json &js, muduo::Timestamp time);
    // 登出业务
    void LoginOut(const muduo::net::TcpConnectionPtr &conn, json &js, muduo::Timestamp time);
    // 注册业务
    void Register(const muduo::net::TcpConnectionPtr &conn, json &js, muduo::Timestamp time);
    // 客户端退出处理
    void ClinetConnetionException(const muduo::net::TcpConnectionPtr &conn);
    // 服务器异常退出处理
    void reset();
    // 个人聊天业务
    void OneChat(const muduo::net::TcpConnectionPtr &conn, json &js, muduo::Timestamp time);
    // 添加好友
    void AddFriend(const muduo::net::TcpConnectionPtr &conn, json &js, muduo::Timestamp time);
    // 创建群组
    void CreatGroup(const muduo::net::TcpConnectionPtr &conn, json &js, muduo::Timestamp time);
    // 加入群组
    void AddGroup(const muduo::net::TcpConnectionPtr &conn, json &js, muduo::Timestamp time);
    // 更改群成员的职位
    void ChangeRole(const muduo::net::TcpConnectionPtr &conn, json &js, muduo::Timestamp time);
    // 群组聊天
    void GroupChat(const muduo::net::TcpConnectionPtr &conn, json &js, muduo::Timestamp time);
    // 这是redis回调函数，可随时接收redisPublish来的信息
    void RedisRecvicePublishHanlder(int id, std::string message);

    handler getHandler(int messageid);

private:
    ChatService();

private:
    // 将MegType类设置为单例模式类
    std::unordered_map<int, handler> _megHandlerMap;

    // 管理用户的链接，这样我们的服务器才知道把接受的信息发送给谁
    std::unordered_map<int, muduo::net::TcpConnectionPtr> _userConnectionMap;

    // 定义一把互斥锁解决线程安全问题
    std::mutex _mutex;

    // 操作各种数据库操作的成员变量
    UserModel _userModel;
    OfflineMessageModel _offMsgModel;
    FriendModel _friendModel;
    GroupModel _groupModel;

    // 操作redis缓存队列的成员变量
    Redis _redis;
};

#endif